/*********测试简单的申请与释放***********/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include "hisi_l0_mem_pool.h"

//#define MEM_SIZE 5 * 1024 * 1024 // 申请4KB内存
#define MEM_SIZE 8192
static void *pool_handle1 = NULL;
static void *pool_handle2 = NULL;
static void *pool_handle3 = NULL;
static void *pool_handle4 = NULL;

static char *alloc_mem(void **pool_handle, int size)
{
	phys_addr_t phys;
	void * test;

	char *kernel_buffer = NULL;
	/* 1. 申请内存 */
	kernel_buffer = l0_kmalloc(size, 0);
	if (!kernel_buffer) {
		pr_err("Failed to allocate memory\n");
		return NULL;
	}
        test = kmalloc(100, GFP_KERNEL);
        pr_info("Allocated test at address %pK\n", test);

	pr_info("Allocated %d bytes at address %pK\n", size, kernel_buffer);

	/* 2. 写入数据 */
	memset(kernel_buffer, 0, size); // 填充0xAA
	strncpy(kernel_buffer, "Hello from kernel space!", 1024);

	printk(KERN_INFO "Buffer content: %s\n", kernel_buffer);
	phys = virt_to_phys(kernel_buffer);
	printk("Physical address: %pap\n", &phys);

	return kernel_buffer;
}

static void free_mem(void *pool_handle, char *kernel_buffer)
{
	/* 4. 释放内存 */
	if (kernel_buffer) {
		l0_kfree(kernel_buffer);
		pr_info("Memory freed\n");
	}
}

static int __init mem_module_init(void)
{
	char *kernel_buffer1;
	char *kernel_buffer2;
	char *kernel_buffer3;
	char *kernel_buffer4;
	kernel_buffer1 = alloc_mem(&pool_handle1, MEM_SIZE);
	if (kernel_buffer1 == NULL) {
		pr_err("Failed to allocate memory\n");
		return -ENOMEM;
	}

	kernel_buffer2 = alloc_mem(&pool_handle2, MEM_SIZE * 2);
	if (kernel_buffer2 == NULL) {
		pr_err("Failed to allocate memory\n");
		return -ENOMEM;
	}
	kernel_buffer3 = alloc_mem(&pool_handle3, MEM_SIZE / 2);
	if (kernel_buffer3 == NULL) {
		pr_err("Failed to allocate memory\n");
		return -ENOMEM;
	}
	kernel_buffer4 = alloc_mem(&pool_handle4, MEM_SIZE / 3);
	if (kernel_buffer4 == NULL) {
		pr_err("Failed to allocate memory\n");
		return -ENOMEM;
	}
	printk(KERN_INFO "kernel_buffer1 %p kernel_buffer2 %p\n",
	       kernel_buffer1, kernel_buffer2);
	free_mem(pool_handle1, kernel_buffer1);
	free_mem(pool_handle2, kernel_buffer2);
	free_mem(pool_handle3, kernel_buffer3);
	free_mem(pool_handle4, kernel_buffer4);
	return 0;
}

static void __exit mem_module_exit(void)
{
	pr_info("mem_module_exit\n");
}

module_init(mem_module_init);
module_exit(mem_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Kernel memory R/W demo");
